#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""异常处理中间件模块

此模块提供了统一的异常处理中间件，用于捕获和处理应用程序中的各类异常，并返回标准化的错误响应格式。
"""
import logging
from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse
from exceptions.custom_exceptions import APIException, ValidationException, ResourceNotFoundException, \
    InternalServerException, ServiceUnavailableException, AuthenticationException, AuthorizationException

import logging
from log_config import setup_logging

setup_logging()
logger = logging.getLogger(__name__)


def setup_exception_handlers(app):
    """
    设置统一的异常处理中间件
    
    为FastAPI应用程序注册各类异常的处理器，确保所有异常都能返回标准化的错误响应格式。
    
    :param app: FastAPI应用实例
    """
    
    @app.exception_handler(APIException)
    async def api_exception_handler(request: Request, exc: APIException):
        """\处理自定义API异常
        
        :param request: 当前请求对象
        :param exc: 自定义API异常实例
        :return: 标准化的错误响应JSON
        """
        logger.error(f"API异常 - {exc.error_type}: {exc.detail} - 路径: {request.url.path}")
        return JSONResponse(
            status_code=exc.status_code,
            content={
                "success": False,
                "error_type": exc.error_type,
                "message": exc.detail,
                "path": request.url.path
            }
        )
    
    @app.exception_handler(HTTPException)
    async def http_exception_handler(request: Request, exc: HTTPException):
        """处理FastAPI内置的HTTP异常
        
        :param request: 当前请求对象
        :param exc: HTTP异常实例
        :return: 标准化的错误响应JSON
        """
        error_type_map = {
            400: "validation_error",
            401: "authentication_error",
            403: "authorization_error",
            404: "resource_not_found",
            422: "validation_error",
            500: "internal_server_error"
        }
        error_type = error_type_map.get(exc.status_code, "http_error")
        logger.error(f"HTTP异常 - {error_type}: {exc.detail} - 路径: {request.url.path}")
        return JSONResponse(
            status_code=exc.status_code,
            content={
                "success": False,
                "error_type": error_type,
                "message": exc.detail,
                "path": request.url.path
            }
        )
    
    @app.exception_handler(Exception)
    async def generic_exception_handler(request: Request, exc: Exception):
        """处理所有未捕获的异常
        
        作为兜底的异常处理器，捕获所有未被特定处理器处理的异常
        
        :param request: 当前请求对象
        :param exc: 未捕获的异常实例
        :return: 标准化的内部错误响应JSON
        """
        logger.error(f"未处理的异常 - 路径: {request.url.path}", exc_info=True)
        return JSONResponse(
            status_code=500,
            content={
                "success": False,
                "error_type": "internal_server_error",
                "message": "服务器内部错误，请稍后重试",
                "path": request.url.path
            }
        )
    
    # 为了保持兼容性，保留原来的404处理器
    @app.exception_handler(404)
    async def custom_404_handler(request: Request, exc: HTTPException):
        """自定义404错误处理器
        
        对特定路径返回空响应，其他路径返回标准404错误
        
        :param request: 当前请求对象
        :param exc: HTTP异常对象
        :return: JSON响应
        """
        if request.url.path in ["/favicon.ico", "/.well-known/appspecific/com.chrome.devtools.json"]:
            return JSONResponse(content={}, status_code=200)
        
        logger.warning(f"404未找到 - 路径: {request.url.path}")
        return JSONResponse(
            status_code=404,
            content={
                "success": False,
                "error_type": "resource_not_found",
                "message": "请求的资源不存在",
                "path": request.url.path
            }
        )